package org.apache.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.dao.CookieDAO;
import org.apache.dao.SettledContractDAO;
import org.apache.dto.Cookies;
import org.apache.factory.Manager;
import org.apache.model.Contract;
import org.apache.model.Event;
import org.apache.model.SettledContract;
import org.apache.service.AIService;
import org.apache.service.AbstractService;
import org.apache.service.BrowserService;
import org.apache.service.ContractService;
import org.apache.service.EventService;
import org.apache.service.SettledContractService;
import org.apache.util.Bet365;
import org.apache.util.CalcUtil;
import org.apache.util.Constant;
import org.apache.util.LogUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BrowserServiceImpl extends AbstractService implements BrowserService, Constant, Bet365 {

    @Autowired
    private CookieDAO cookieDAO;

    @Autowired
    private EventService eventService;

    @Autowired
    private ContractService contractService;

    @Autowired
    private AIService aiService;

    @Autowired
    private SettledContractDAO settledContractDAO;

    @Autowired
    private SettledContractService settledContractService;

    @Override
    public List<Event> listAllEvent() {

        return null;
    }

    Cookies cookies = new Cookies();
    Map<String, String> headers = prepareBasicHeaders();

    public void navigator() {

        if (cookieDAO.findAll() != null && cookieDAO.findAll().size() > 0) {
            // re-store cookie for logined session or basic session for the first time
            if (cookies.getCookies() == null) {
                cookies.setCookies(cookieDAO.findAll());
            }
            headers.put(COOKIE, cookies.getCookie());
        } else {
            try {
                redirectNavigator(DEFAULT_URL, headers, cookies);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void exposeEvents() {

        try {
            navigator();
            // go to In-Play -> Soccer
            Document soccers = redirectNavigator(SOCCER_IN_PLAY_URL, headers, null);
            // trích xuất events from soccers in-play page
            Elements eEvents = soccers.select("div.Level2");
            List<Event> events = eventService.parseEvent(eEvents);
            // persist events
            events = eventService.persistEvent(events);
            LogUtil.logs(events);
            List<Contract> qualifyContracts = contractService.exposeContract(events, headers, cookies);
            if (qualifyContracts != null && qualifyContracts.size() > 0) {
                Contract bestContract = aiService.getBestContract(qualifyContracts);
                if (bestContract != null) {
                    Manager.STATUS = 1; // place bet - waiting for finish
                    aiService.virtualPlaceBet(bestContract);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // Sorry, this page is no longer available. Betting has closed or has been suspended.
    @Override
    public void waitingResult() {

        try {
            System.out.println("::Waiting result : " + new Date());
            SettledContract running = settledContractDAO.getRunningSettledContract();
            if (running != null) {
                Event runningEvent = settledContractService.getRunningEvent(running);
                Document runningPage = null;
                try {
                    runningPage = redirectNavigator(runningEvent.getLocation(), headers, cookies);
                    // update running event
                    List<Event> events = new ArrayList<Event>();
                    events.add(runningEvent);
                    eventService.persistEvent(events);
                } catch (Exception e) {
                    System.out.println(" waitingResult -> redirectNavigator OR persist event error ");
                }
                if (runningPage.select(".Score").size() > 0) {
                    Element eScore = runningPage.select(".Score").get(0);
                    // update running settled contract
                    running.setCurrentGoal(CalcUtil.getTotalGoal(eScore.text()));
                    System.out.println(eScore.text());
                    settledContractDAO.update(running);
                } else {
                    Element eFinish = runningPage.select(".Level1").get(0);
                    if (eFinish != null) {
                        if (eFinish.text().indexOf("this page is no longer available") > -1 && runningEvent.getPlayTime() >= 85) {
                            // finished - update all running settled contract to false
                            // check result
                            Manager.STATUS = 0; // re-call expose events in manager thread
                            settledContractService.updateAllRunningToFalse();
                            Boolean result = aiService.calcResult(running);

                            System.out.println();
                            System.out.println();
                            System.out.println(":::::::::::::::::::::::::::::::::::::");
                            System.out.println(":::::::::::::::::::::::::::::::::::::");
                            System.out.println("Event finised - Result : " + result);
                            System.out.println(":::::::::::::::::::::::::::::::::::::");
                            System.out.println(":::::::::::::::::::::::::::::::::::::");
                            System.out.println();
                            System.out.println();
                        }
                    }
                }
            } else {
                Manager.STATUS = 0;
            }
        } catch (Exception e) {
            System.out.println("waitingResult error");
            e.printStackTrace();
        }
    }
}
